home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Online / hsc / source / hsclib / include.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-02  |  8.8 KB  |  336 lines

  1. /*
  2.  * This source code is part of hsc, a html-preprocessor,
  3.  * Copyright (C) 1995-1997  Thomas Aglassinger
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20. /*
  21.  * hsclib/include.c
  22.  *
  23.  * hsc include functions
  24.  *
  25.  * updated: 16-May-1997
  26.  * created: 19-Feb-1996
  27.  */
  28.  
  29. #include <time.h>
  30.  
  31. #include "hsclib/inc_base.h"
  32.  
  33. #include "ugly/ufile.h"
  34. #include "ugly/fname.h"
  35.  
  36. #include "hsclib/input.h"
  37. #include "hsclib/parse.h"
  38.  
  39. #define NOEXTERN_HSCLIB_INCLUDE_H
  40. #include "hsclib/include.h"
  41.  
  42. /*
  43.  * hsc_include
  44.  *
  45.  * read from inpf, parse for hsc-commands and execute them,
  46.  * check for html-error,
  47.  * write all out to outf and close input file.
  48.  *
  49.  * params: inpfnm...input file name
  50.  *         outf.....output file structure, already opended
  51.  *
  52.  * result: TRUE, if all worked well, else FALSE
  53.  */
  54. static BOOL hsc_include(HSCPRC * hp, INFILE * inpf, ULONG optn, INFILEPOS * base_pos)
  55. {
  56.     BOOL ok;                    /* result */
  57.     ok = (inpf != NULL);
  58.  
  59.     if (optn & IH_POS_PARENT)
  60.     {
  61.         panic("IH_POS_PARENT set");
  62.     }
  63.  
  64.     if (inpf)                   /* file opened? */
  65.     {                  
  66. #if (defined MSDOS) /* HSC_YOUR */
  67.         /* check input > 32K */
  68.         if (estrlen(inpf->lnbuf) > (32*1024))
  69.         {
  70.             fprintf(stderr, "** input file too huge\n");
  71.             exit(RC_FAIL);
  72.         }
  73. #endif
  74.         /* push current input file on input-file-stack */
  75.         if (hp->inpf)
  76.         {
  77.             ins_dlnode(hp->inpf_stack, hp->inpf_stack->first, (APTR) hp->inpf);
  78.         }
  79.  
  80.         /* set new base position for input-file */
  81.         /* (if called from a macro or after eg. <$source>) */
  82.         if (base_pos)
  83.         {
  84.             set_infile_base(inpf, base_pos);
  85.         }
  86.  
  87.         /* assign new input file to hsc-process */
  88.         hp->inpf = inpf;
  89.  
  90.         /* hide status? */
  91.         if ((optn & IH_PARSE_MACRO) || (optn & IH_PARSE_MACRO))
  92.         {
  93.             optn |= IH_NO_STATUS;
  94.         }
  95.  
  96.         /* set char-parse methods */
  97.         inpf->is_nc = hsc_normch;       /* set is_nc-methode */
  98.         inpf->is_ws = hsc_whtspc;       /* set is_ws-methode */
  99.  
  100.         /* status message: reading new file */
  101.         if (!(optn & IH_NO_STATUS) && !infeof(inpf))
  102.         {
  103.             hsc_status_file_begin(hp, infget_fname(hp->inpf));
  104.         }
  105.  
  106.         /* parse file */
  107.         while (!infeof(inpf) && ok)
  108.         {
  109.             if (!(optn & IH_NO_STATUS) &&
  110.                 (hp->prev_status_line != infget_y(hp->inpf))
  111.                 )
  112.             {
  113.                 /* status message */
  114.                 hsc_status_line(hp);
  115.                 hp->prev_status_line = infget_y(hp->inpf);
  116.             }
  117.  
  118.             /* parse next item */
  119.             if (optn & IH_PARSE_SOURCE)
  120.             {
  121.                 ok = hsc_parse_source(hp);
  122.             }
  123.             else
  124.             {
  125.                 ok = hsc_parse(hp);
  126.             }
  127.         }
  128.  
  129.         /* parse at end: check for missing tags, .. */
  130.         if (ok && (optn & IH_PARSE_END))
  131.         {                       /* parse end (unclosed tags etc) */
  132.             ok = hsc_parse_end(hp);
  133.  
  134.             if (ok && (optn & IH_UPDATE_PRJ))
  135.             {
  136.                 /* update project file */
  137.                 ok = hsc_parse_end_id(hp);
  138.             }
  139.         }
  140.  
  141.         /* end of file status */
  142.         if (!(optn & IH_NO_STATUS))
  143.         {
  144.             /* status message: file processed */
  145.             hsc_status_file_end(hp);
  146.         }
  147.  
  148.         /* close file */
  149.         infclose(hp->inpf);
  150.  
  151.         /* pull previous input file from input-file-stack
  152.          * or end hsc-process */
  153.         if (hp->inpf_stack->first)
  154.         {
  155.             /* pull first item from stack */
  156.             hp->inpf = (INFILE *) hp->inpf_stack->first->data;
  157.             hp->inpf_stack->first->data = NULL;
  158.  
  159.             del_dlnode(hp->inpf_stack, hp->inpf_stack->first);
  160.         }
  161.         else
  162.         {
  163.             hp->inpf = NULL;
  164.         }
  165.     }
  166.     else
  167.     {
  168.         panic("no input file");
  169.     }
  170.  
  171.     return (ok);
  172. }
  173.  
  174. /*
  175.  * hsc_include_file
  176.  *
  177.  * open input file and include it
  178.  */
  179. BOOL hsc_base_include_file(HSCPRC * hp, STRPTR filename, ULONG optn, INFILEPOS * base_pos)
  180. {
  181.     BOOL ok = FALSE;
  182.     INFILE *inpf = NULL;
  183.  
  184.     /* status message: reading input */
  185.     if (!(optn & (IH_PARSE_MACRO | IH_PARSE_HSC)))
  186.     {
  187.         hsc_status_file_begin(hp, filename);
  188.     }
  189.  
  190.     /* check for stdin to use as input-file */
  191.     if (!strcmp(filename, FILENAME_STDIN))
  192.         filename = NULL;
  193.  
  194.     /* open & read input file */
  195.     errno = 0;
  196.     inpf = infopen(filename, ES_STEP_INFILE);
  197.  
  198.     if (inpf)
  199.     {
  200.         /* include opened file */
  201.         ok = hsc_include(hp, inpf, optn, base_pos);
  202.  
  203.         /* check if this file is the main-source-file
  204.          * or an include-file and update project-data
  205.          * if neccessary
  206.          */
  207.         if (ok && hp->project)
  208.         {
  209.             if (optn & IH_IS_SOURCE)
  210.             {
  211.                 if (!filename)
  212.                     filename = FILENAME_STDIN;
  213.                 D(fprintf(stderr, DHL "INCLUDE source: `%s'\n", filename));
  214.                 hsc_project_set_source(hp->project, filename);
  215.                 /*reallocstr(&(hp->document->sourcename), filename); */
  216.             }
  217.  
  218.             /* check if this file is an include-file
  219.              * and update project-data if neccessary */
  220.             if (filename && (optn & IH_IS_INCLUDE))
  221.             {
  222.                 D(fprintf(stderr, DHL "INCLUDE subfile: `%s'\n", filename));
  223.                 hsc_project_add_include(hp->project, filename);
  224.             }
  225.         }
  226.     }
  227.     else
  228.     {
  229.         hsc_msg_noinput(hp, filename);  /* couldn't open file */
  230.     }
  231.  
  232.     return (ok);
  233. }
  234.  
  235. /*
  236.  * hsc_include_string
  237.  *
  238.  * open string as input file and include it
  239.  */
  240. BOOL hsc_base_include_string(HSCPRC * hp, STRPTR filename, STRPTR s, ULONG optn, INFILEPOS * base_pos)
  241. {
  242.     BOOL ok;
  243.     INFILE *inpf = NULL;
  244.  
  245.     if (optn & IH_POS_PARENT)
  246.     {
  247.         filename = PARENT_FILE_ID;
  248.         optn &= ~IH_POS_PARENT;
  249.     }
  250.     inpf = infopen_str(filename, s, 0);         /* try to open input file */
  251.  
  252.     ok = hsc_include(hp, inpf, optn, base_pos);
  253.  
  254.     return (ok);
  255. }
  256.  
  257. /*
  258.  * find_includefile
  259.  *
  260.  * scan all include-directories for file to be opened;
  261.  * if the file can't be found, the filename in the current
  262.  * directory will be returned (which should therefor result
  263.  * in an error while processing hsc_include())
  264.  *
  265.  * NOTE: this function considers the file to be found if it could have
  266.  *       been opened for input. afterwards, the file is immediatly
  267.  *       closed. This isn't really a multitasking-conform behavior
  268.  *       because the file will have to be reopend again by the
  269.  *       hsc_include() function later and meanwhile could have been
  270.  *       removed by another task.
  271.  */
  272. static BOOL find_includefile(HSCPRC *hp, EXPSTR * dest, STRPTR filename)
  273. {
  274.     BOOL found = FALSE;
  275.  
  276.     /* reset filename */
  277.     set_estr(dest, filename);
  278.  
  279.     if (!fexists(filename))
  280.     {
  281.         DLNODE *nd = dll_first(hp->include_dirs);
  282.  
  283.         /* process all include-directories.. */
  284.         while (nd && !found)
  285.         {
  286.             /* concat incdir+filename, check if it exists,
  287.              * process next or abort loop */
  288.             link_fname(dest, (STRPTR) dln_data(nd), filename);
  289.             D(fprintf(stderr, DHL "  try `%s'\n", estr2str(dest)));
  290.             if (fexists(estr2str(dest)))
  291.             {
  292.                 found = TRUE;
  293.             }
  294.             else
  295.                 nd = dln_next(nd);
  296.         }
  297.     }
  298.     else
  299.     {
  300.         /* found in current directory */
  301.         found = TRUE;
  302.     }
  303.  
  304.     if (found)
  305.     {
  306.         D(fprintf(stderr, DHL "  found at `%s'\n", estr2str(dest)));
  307.     }
  308.  
  309.     return (found);
  310. }
  311.  
  312. /* hsc_include_file: include file without base-position */
  313. BOOL hsc_include_file(HSCPRC * hp, STRPTR filename, ULONG optn)
  314. {
  315.     BOOL ok = FALSE;
  316.     EXPSTR *real_filename = init_estr(64);
  317.  
  318.     /* scan include directories */
  319.     find_includefile(hp, real_filename, filename);
  320.  
  321.     /* now include file */
  322.     ok = hsc_base_include_file(hp, estr2str(real_filename), optn, NULL);
  323.  
  324.     /* cleanup */
  325.     del_estr(real_filename);
  326.  
  327.     return ok;
  328. }
  329.  
  330. /* hsc_include_string: include string without base-position */
  331. BOOL hsc_include_string(HSCPRC * hp, STRPTR filename, STRPTR s, ULONG optn)
  332. {
  333.     return (hsc_base_include_string(hp, filename, s, optn, NULL));
  334. }
  335.  
  336.